package timer

import (
	awesomeTask "awesomeTask/commom"
	"strconv"
	"sync"
	"time"
)

var Second int64 = 1
var Minute int64 = Second * 60
var Hour int64 = Minute * 60
var Day int64 = Hour * 24
var Week int64 = Day * 7
var registerTask map[string]map[string]interface{} = make(map[string]map[string]interface{})
var registerTaskMap sync.Map
var taskNum int = 0

func addTask(fun func(), tick int64, runNum int) int {
	taskNum += 1
	taskInfo := make(map[string]interface{})
	if runNum > 0 {
		taskInfo["runTime"] = awesomeTask.NowInt() + tick
	} else {
		taskInfo["runTime"] = awesomeTask.NowInt()
	}

	taskInfo["runNum"] = runNum
	taskInfo["runTask"] = fun
	taskInfo["tick"] = tick
	taskInfo["id"] = strconv.Itoa(taskNum)
	taskInfo["status"] = true
	taskInfo["callBack"] = func() {
		/**
		负一表示永久执行
		*/
		if taskInfo["runNum"] != -1 {
			taskInfo["runNum"] = taskInfo["runNum"].(int) - 1
		}
		if taskInfo["runNum"] == 0 {
			deleteTask(awesomeTask.ParseInt(taskInfo["id"].(string)))
			return
		}
		taskInfo["runTime"] = tick + awesomeTask.NowInt()
		registerTaskMap.Store(taskInfo["id"].(string), taskInfo)
	}
	registerTaskMap.Store(taskInfo["id"].(string), taskInfo)
	return taskNum
}
func deleteTask(taskId int) {
	if _, ok := registerTaskMap.Load(strconv.Itoa(taskId)); ok {
		registerTaskMap.Delete(strconv.Itoa(taskId))
	}
}
func ClearTimer(taskId int) {
	deleteTask(taskId)
}

/**
执行一次
*/
func SetTimeOut(fun func(), tick int64) int {
	return addTask(fun, tick, 1)
}

/**
执行多次
*/
func SetTimeInterval(fun func(), tick int64) int {
	return addTask(fun, tick, -1)
}
func SetTimeByNum(fun func(), tick int64, runNum int) int {
	return addTask(fun, tick, runNum)
}
func InitTimer() {
	go runTimer()
}
func runTimer() {
	for true {
		registerTaskMap.Range(func(key, value interface{}) bool {
			taskInfo := value.(map[string]interface{})
			if taskInfo["runTime"].(int64) <= awesomeTask.NowInt() {
				fun := taskInfo["runTask"].(func())
				go fun()
				callBack := taskInfo["callBack"].(func())
				callBack()
			}
			return true
		})
		time.Sleep(time.Duration(1) * time.Second)
	}
}
